package cn.xiaopengstack.domain.trade.model.valobj;

import cn.xiaopengstack.domain.trade.rule.refund.IRefundStrategy;
import cn.xiaopengstack.domain.trade.rule.refund.PaidFormedToRefundStrategy;
import cn.xiaopengstack.domain.trade.rule.refund.PaidUnformedToRefundStrategy;
import cn.xiaopengstack.domain.trade.rule.refund.UnpaidToUnlockStrategy;
import cn.xiaopengstack.types.enums.ResponseCode;
import cn.xiaopengstack.types.exception.AppException;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

/**
 * @author jiangyangang
 */

@AllArgsConstructor
@Getter
public enum RefundTypeEnumVO {
    unpay_unlock("unpaid_unlock", UnpaidToUnlockStrategy.class, "未支付退单") {
        @Override
        public boolean matches(GroupBuyOrderStatusEnum groupBuyOrderStatusEnum, GroupBuyOrderListStatusEnum groupBuyOrderListStatusEnum) {
            return GroupBuyOrderStatusEnum.GROUPING == groupBuyOrderStatusEnum && GroupBuyOrderListStatusEnum.INIT_LOCK == groupBuyOrderListStatusEnum;
        }
    },
    paid_unformed("paid_unformed", PaidUnformedToRefundStrategy.class, "未成团已支付退单") {
        @Override
        public boolean matches(GroupBuyOrderStatusEnum groupBuyOrderStatusEnum, GroupBuyOrderListStatusEnum groupBuyOrderListStatusEnum) {
            return GroupBuyOrderStatusEnum.GROUPING == groupBuyOrderStatusEnum && GroupBuyOrderListStatusEnum.COMPLETE == groupBuyOrderListStatusEnum;

        }
    },
    paid_formed("paid_formed", PaidFormedToRefundStrategy.class, "已成团已支付退单") {
        @Override
        public boolean matches(GroupBuyOrderStatusEnum groupBuyOrderStatusEnum, GroupBuyOrderListStatusEnum groupBuyOrderListStatusEnum) {
            return GroupBuyOrderStatusEnum.GROUP_COMPLETE == groupBuyOrderStatusEnum && GroupBuyOrderListStatusEnum.COMPLETE == groupBuyOrderListStatusEnum ||
                    GroupBuyOrderStatusEnum.GROUP_COMPLETE_REFUND == groupBuyOrderStatusEnum && GroupBuyOrderListStatusEnum.COMPLETE == groupBuyOrderListStatusEnum;
        }
    },
    ;

    private final String code;

    private final Class<? extends IRefundStrategy> strategy;

    private final String info;

    public static RefundTypeEnumVO getType(GroupBuyOrderStatusEnum groupBuyOrderStatusEnum, GroupBuyOrderListStatusEnum groupBuyOrderListStatusEnum){
        return Stream.of(RefundTypeEnumVO.values()).filter(type -> type.matches(groupBuyOrderStatusEnum, groupBuyOrderListStatusEnum))
                .findAny()
                .orElseThrow(() -> new AppException(ResponseCode.TRADE_REFUND_UNKNOW_TYPE));
    }


    public abstract boolean matches(GroupBuyOrderStatusEnum groupBuyOrderStatusEnum, GroupBuyOrderListStatusEnum groupBuyOrderListStatusEnum);
}
